const schedule = require('node-schedule');

const secondCommentCollection = 'secondComment';
const timeTaskCollection = 'timeTask';

const getCounts = (getCollectionCounts, collection) => async (req, res) => {
    const counts = await getCollectionCounts({ collection });
    return res ? res.json(counts) : counts;
}

//总博客数量
const getBlogCounts = (getCollectionCounts) => getCounts(getCollectionCounts, 'blog');
//总博客标签数量
const getBlogTagsCounts = (getCollectionCounts) => getCounts(getCollectionCounts, 'blogTag');
//总扑克卡片数量
const getPokerCounts = (getCollectionCounts) => getCounts(getCollectionCounts, 'poker');
//总浏览数
const getAllBrowseCounts = (aggregate) => async (req, res) => {
    const result = await aggregate({
        collection: 'blog',
        pipeline: [{ $group: { _id: null, counts: { $sum: '$browseCount' } } }]
    })
    console.log("getAllBrowseCounts:", result);
    if (result && result.length) return res ? res.json(result[0].counts) : result[0].counts
    else res.json(0);
}
//总评论数 
const getAllCommentCounts = (getCollectionCounts) => async (req, res) => {
    const first = await getCounts(getCollectionCounts, 'comment')();
    const second = await getCounts(getCollectionCounts, secondCommentCollection)();
    console.log(`一级评论：${first},二级评论：${second}`);
    const total = first + second;

    return res ? res.json(total) : total;
};

//TODO 总点赞数
const getAllThumbsUpCounts = (aggregate) => async (req, res) => {
    const result = await aggregate({
        collection: 'blog',
        pipeline: [{ $group: { _id: null, counts: { $sum: '$thumbsUp' } } }]
    })
    console.log("getAllThCounts:", result);
    if (result && result.length) res.json(result[0].counts)
    else res.json(0);
}

//总账户数
const getAllAccountCounts = (getCollectionCounts) => getCounts(getCollectionCounts, 'userProfile');

//返回7天 数据
const getDashboardData = ({ findData }) => async (req, res) => {
    const { day = 7 } = req.query;
    console.log(`获取${day}天的数据`);
    const data = await findData({ collection: "dashboard", limit: Number(day), sort: { _id: -1 } });
    console.log(data);
    res.json({ message: '获取成功', data: data.reverse() });
}

// 每天0时将当前数据,新增数据记录。
//"newBlogs", 'newBrowse', 'newComment' 'totalBlogs' 'totalBrowse' 'totalComment'
const scheduleJob = ({ getCollectionCounts, aggregate, findData, insertOne }) => {
    //'0 0 0 * * *' => 每天0点0分0秒执行
    schedule.scheduleJob('0 0 0 * * *', async function () {
        const totalBlogs = await getBlogCounts(getCollectionCounts)();
        const totalBrowse = await getAllBrowseCounts(aggregate)();
        const totalComment = await getAllCommentCounts(getCollectionCounts)();
        console.log("totalBlogs:", totalBlogs)
        //取最后一项 即为昨天的数据
        const [yesterday] = await findData({ collection: 'dashboard', limit: 1, sort: { _id: -1 } })
        console.log('上一条数据', yesterday);
        const item = {
            newBlogs: totalBlogs - yesterday.totalBlogs,
            newBrowse: totalBrowse - yesterday.totalBrowse,
            newComment: totalComment - yesterday.totalComment,
            totalBlogs,
            totalBrowse,
            totalComment,
        };
        console.log('今天的数据:', item);
        const insert = await insertOne('dashboard', item);
        console.log("插入数据:", insert);
    });
};

// ********** 定时任务 *************

/**
 * @description: 向数据库中添加一条定时任务记录
 * @param {string} content 任务内容
 * @param {string} interval 时间间隔
 * @param {mail} mail 提醒邮箱
 */
const createTimeTask = (insertOne) => async (req, res) => {
    console.log(`每隔 ${req.payload.interval}小时提醒${req.payload.mail} ${req.payload.content}`);
    console.log(req.payload);
    const result = await insertOne(timeTaskCollection, req.payload);
    if (result) res.json({ message: '创建任务成功' });
}

/**
 * @description: 删除数据库中的任务记录
 * @param {string} taskId _id 
 */
const deleteTimeTask = (deleteOne) => async (req, res) => {
    const result = await deleteOne(timeTaskCollection, req.payload.id);
    if (result) res.json({ message: '删除成功' });
}

/**
 * @description: 更改数据库中一条定时任务记录
 * @param {string} content 任务内容
 * @param {string} interval 时间间隔
 * @param {_id} _id 任务id
 */
const updateTimeTask = (updateOne) => async (req, res) => {
    const { _id, ...data } = req.payload;
    console.log("更改任务：", req.payload);
    const result = await updateOne({ collection: timeTaskCollection, _id, data });

    console.log("更改任务：", result);
    if (result) res.json({ message: '更新任务成功' });
}

/**
 * @description: 查询数据库中绑定在某邮箱上的任务记录
 * @param {mail} mail 
 */
const queryTimeTaskByMail = (findData) => async (req, res) => {
    const list = await findData({ collection: timeTaskCollection, find: { mail: req.payload.mail } });
    if (list) res.json({ message: '查询成功', list });
}

// 晚10-早7不执行
const startHour = 7;
const endHour = 22;
const payloadHours = endHour - startHour;// 15 共有多少个小时有效执行任务

/**
 * @description: 定时重复任务
 * @param {string} content 任务内容
 * @param {string} interval 时间间隔
 * @param {mail} mail 提醒邮箱
 */
const startTimeTask = async (findData, sendMail) => {
    //创建重复规则
    const rule = new schedule.RecurrenceRule();
    rule.hour = [];//早7-晚10执行  [7,8,9,10 ... 21]
    rule.minute = [0, 30];
    rule.second = 0;

    let i = 0;
    while (i < payloadHours) {
        rule.hour.push(startHour + i);
        i++;
    }
    //查询满足条件并发送
    const repeat = async () => {
        const data = new Date();
        const hours = data.getHours();
        const minutes = data.getMinutes();// 0  /  30

        //开始小时不执行 例如 7点开始则 7点整不执行 7点半执行
        if (hours === startHour && !minutes) return;

        const interval = ["0.5"];//每隔半个小时执行 所以半小时任务一定符合

        const diffHour = hours - startHour;

        if (diffHour) {//找到能被整除的数
            // '<' 目的是少比较一次,自己肯定能被整除啦
            for (let i = minutes ? 2 : 1; i < diffHour; i++) {
                if (diffHour % i === 0) interval.push(i.toString());
            }
            !minutes && interval.push(diffHour.toString());
        }

        const list = await findData({
            collection: timeTaskCollection,
            find: { interval: { $in: interval } }
        });
        console.log({ interval, list });
        list.forEach(({ mail, content }) => {
            console.log(`提醒${mail} ${content} --${data.toLocaleString()}任务 `);
            sendMail({
                message: content, mail,
                subject: content, from: "定时提醒 <2218176087@qq.com>"
            });
        });
    }

    schedule.scheduleJob(rule, repeat);
}

module.exports = {
    getBlogCounts, getBlogTagsCounts, getPokerCounts, getAllBrowseCounts, getAllAccountCounts, getAllCommentCounts, getAllThumbsUpCounts, scheduleJob, getDashboardData,
    createTimeTask,
    deleteTimeTask,
    queryTimeTaskByMail,
    startTimeTask,
    updateTimeTask
};
